package com.example.service;

import cn.hutool.core.util.TypeUtil;
import com.example.dao.BaseDao;
import com.example.entity.BaseEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.lang.reflect.Type;

/**
 * @author chentao
 * @create 2023/3/11 15:53
 * @since 1.0.0
 */
public class BaseServiceImpl<D extends BaseDao<T>, T extends BaseEntity> implements BaseService<T> {

    Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private D dao;

    @Resource
    private BaseDispatcherService<T> baseDispatcherService;

    @Transactional
    @Override
    public T add(T entity) {
        entity.recalculate();
        T t = this.dao.save(entity);
        this.baseDispatcherService.add(entity);
        return t;
    }

    @Transactional
    @Override
    public void delete(T entity) {
        this.baseDispatcherService.delete(entity);
        this.dao.delete(entity);
    }

    @Transactional
    @Override
    public void deleteById(Long id) {
        T entity = getById(id);
        this.delete(entity);
    }

    @Override
    public T getById(Long id, Boolean noLazy) {
        if (noLazy) {
            return getById(id);
        } else {
            return this.dao.getOne(id);
        }
    }

    @Override
    public T getById(Long id) {
        T entity = this.dao.findById(id).get();
        this.baseDispatcherService.get(entity);
        return entity;
    }

    @Override
    public Sort getSort(T entity) {
        return Sort.by(Sort.Direction.DESC, "id");
    }

    @Override
    public Pageable getPageable(T entity) {
        return PageRequest.of(entity.getPageNum(), entity.getPageSize(), getSort(entity));
    }

    @Override
    public Example<T> initSetting(T entity) {
        return Example.of(entity);
    }

    @Override
    public Page<T> findPage(T entity) {
        return this.dao.findAll(this.initSetting(entity), this.getPageable(entity));
    }

    public D getDao() {
        return dao;
    }

    @Override
    public String getEntityName() {
        Type typeArgument = TypeUtil.getTypeArgument(getClass(), 1);
        return typeArgument.getTypeName();
    }
}